package cn.cyh.queue_service.service.impl;

import cn.cyh.queue_service.common.ResultCode;
import cn.cyh.queue_service.exception.BusinessException;
import cn.cyh.queue_service.mapper.QueueMapper;
import cn.cyh.queue_service.mapper.ServiceTypeMapper;
import cn.cyh.queue_service.model.dto.PageRequest;
import cn.cyh.queue_service.model.dto.PageResult;
import cn.cyh.queue_service.model.dto.ServiceTypeRequest;
import cn.cyh.queue_service.model.entity.ServiceType;
import cn.cyh.queue_service.model.vo.ServiceTypeVO;
import cn.cyh.queue_service.service.ServiceTypeService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 业务类型服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ServiceTypeServiceImpl extends ServiceImpl<ServiceTypeMapper, ServiceType> implements ServiceTypeService {
    
    private final ServiceTypeMapper serviceTypeMapper;
    private final QueueMapper queueMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createServiceType(ServiceTypeRequest request) {
        // 验证前缀是否已存在
        ServiceType existingType = getByPrefix(request.getPrefix());
        if (existingType != null) {
            throw new BusinessException(ResultCode.PREFIX_EXISTS);
        }
        
        // 创建业务类型
        ServiceType serviceType = ServiceType.builder()
                .name(request.getName())
                .description(request.getDescription())
                .prefix(request.getPrefix())
                .requireFace(request.getRequireFace() != null ? request.getRequireFace() : 0)
                .status(request.getStatus() != null ? request.getStatus() : 1)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
        
        // 保存
        save(serviceType);
        
        return serviceType.getId();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateServiceType(Long id, ServiceTypeRequest request) {
        // 检查业务类型是否存在
        ServiceType existingType = getById(id);
        if (existingType == null) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_NOT_FOUND);
        }
        
        // 如果前缀有变化，验证新前缀是否已存在
        if (!existingType.getPrefix().equals(request.getPrefix())) {
            ServiceType prefixType = getByPrefix(request.getPrefix());
            if (prefixType != null && !prefixType.getId().equals(id)) {
                throw new BusinessException(ResultCode.PREFIX_EXISTS);
            }
        }
        
        // 更新业务类型
        ServiceType serviceType = ServiceType.builder()
                .id(id)
                .name(request.getName())
                .description(request.getDescription())
                .prefix(request.getPrefix())
                .requireFace(request.getRequireFace())
                .status(request.getStatus())
                .updateTime(LocalDateTime.now())
                .build();
        
        return updateById(serviceType);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteServiceType(Long id) {
        // 检查业务类型是否存在
        ServiceType existingType = getById(id);
        if (existingType == null) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_NOT_FOUND);
        }
        
        // 检查是否有未完成的队列
        LambdaQueryWrapper<cn.cyh.queue_service.model.entity.Queue> queueWrapper = new LambdaQueryWrapper<>();
        queueWrapper.eq(cn.cyh.queue_service.model.entity.Queue::getServiceTypeId, id)
                .in(cn.cyh.queue_service.model.entity.Queue::getStatus, "WAITING", "CALLING", "SERVING");
        
        int count = queueMapper.selectCount(queueWrapper).intValue();
        if (count > 0) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_IN_USE);
        }
        
        // 执行删除
        return removeById(id);
    }
    
    @Override
    public ServiceTypeVO getServiceTypeById(Long id) {
        ServiceType serviceType = getById(id);
        if (serviceType == null) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_NOT_FOUND);
        }
        
        ServiceTypeVO vo = convertToVo(serviceType);
        
        // 获取等待人数
        int waitingCount = queueMapper.countWaitingByServiceType(id);
        vo.setWaitingCount(waitingCount);
        
        return vo;
    }
    
    @Override
    public PageResult<ServiceTypeVO> getServiceTypeList(PageRequest pageRequest) {
        IPage<ServiceType> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        
        // 构建查询条件
        LambdaQueryWrapper<ServiceType> queryWrapper = new LambdaQueryWrapper<>();
        
        // 设置排序
        if (StrUtil.isNotBlank(pageRequest.getOrderBy())) {
            queryWrapper.orderBy(true, 
                    pageRequest.getIsAsc(), 
                    "create_time".equals(pageRequest.getOrderBy()) ? ServiceType::getCreateTime : 
                    "update_time".equals(pageRequest.getOrderBy()) ? ServiceType::getUpdateTime : 
                    ServiceType::getId);
        } else {
            queryWrapper.orderByDesc(ServiceType::getCreateTime);
        }
        
        // 执行分页查询
        page = page(page, queryWrapper);
        
        // 转换为VO并获取等待人数
        List<ServiceTypeVO> voList = page.getRecords().stream()
                .map(type -> {
                    ServiceTypeVO vo = convertToVo(type);
                    int waitingCount = queueMapper.countWaitingByServiceType(type.getId());
                    vo.setWaitingCount(waitingCount);
                    return vo;
                })
                .collect(Collectors.toList());
        
        // 构建分页结果
        return PageResult.<ServiceTypeVO>builder()
                .pageNum(pageRequest.getPageNum())
                .pageSize(pageRequest.getPageSize())
                .total(page.getTotal())
                .pages((int) page.getPages())
                .list(voList)
                .hasPrev(pageRequest.getPageNum() > 1)
                .hasNext(pageRequest.getPageNum() < page.getPages())
                .build();
    }
    
    @Override
    public List<ServiceTypeVO> getActiveServiceTypes() {
        List<ServiceType> typeList = serviceTypeMapper.selectActiveTypes();
        
        return typeList.stream()
                .map(this::convertToVo)
                .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status) {
        // 验证状态值
        if (status != 0 && status != 1) {
            throw new BusinessException(ResultCode.PARAM_ERROR);
        }
        
        // 检查业务类型是否存在
        ServiceType existingType = getById(id);
        if (existingType == null) {
            throw new BusinessException(ResultCode.BUSINESS_TYPE_NOT_FOUND);
        }
        
        // 如果要禁用，检查是否有未完成的队列
        if (status == 0) {
            LambdaQueryWrapper<cn.cyh.queue_service.model.entity.Queue> queueWrapper = new LambdaQueryWrapper<>();
            queueWrapper.eq(cn.cyh.queue_service.model.entity.Queue::getServiceTypeId, id)
                    .in(cn.cyh.queue_service.model.entity.Queue::getStatus, "WAITING", "CALLING", "SERVING");
            
            int count = queueMapper.selectCount(queueWrapper).intValue();
            if (count > 0) {
                throw new BusinessException(ResultCode.BUSINESS_TYPE_IN_USE);
            }
        }
        
        // 更新状态
        LambdaUpdateWrapper<ServiceType> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ServiceType::getId, id)
                .set(ServiceType::getStatus, status)
                .set(ServiceType::getUpdateTime, LocalDateTime.now());
        
        return update(updateWrapper);
    }
    
    @Override
    public ServiceType getByPrefix(String prefix) {
        return serviceTypeMapper.selectByPrefix(prefix);
    }
    
    /**
     * 转换为VO对象
     */
    private ServiceTypeVO convertToVo(ServiceType serviceType) {
        if (serviceType == null) {
            return null;
        }
        
        ServiceTypeVO vo = new ServiceTypeVO();
        BeanUtil.copyProperties(serviceType, vo);
        
        return vo;
    }
} 